package com.lry;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Node {

    public volatile boolean error;
    private int successNum;
    private Integer num;
    private String name;
    private int gap = 5;
    private Redis redis;
    private String key;
    private String errorKey;
    private SegmentLock<String> segmentLock;
    private volatile boolean has = true;

    public Node(int num,String name,String key,String errorKey ,Redis redis){
        this.name = name;
        this.num = num;
        this.redis = redis;
        this.key = key;
        this.errorKey = errorKey;
        this.segmentLock = new SegmentLock<>();
    }

    public String getKey() {
        return key;
    }

    public void secKill(String username){
        if(error){
            log.error("用户{},节点{}秒杀，节点故障",username,name);
            return;
        }
        if(!has){
            log.info("用户{}在节点{}秒杀失败",username,name);
            return;
        }
        try{
            segmentLock.lock(errorKey);
            if(error){
                log.error("用户{},节点{}秒杀，节点故障",username,name);
                return;
            }
            if(!has){
                log.info("用户{}在节点{}秒杀失败",username,name);
                return;
            }

            //本地没有了，尝试去redis拿
            if(num<=0){
                Integer remain = redis.get(errorKey);
                if(null==remain||remain<=0){
                    log.info("用户{}在节点{}秒杀失败,redis",username,name);
                    has = false;
                }else{
                    redis.incr(errorKey,-1);
                    log.info("用户{}在节点{}秒杀成功,redis,remain={}",username,name,remain);//3
                }
                return;
            }else{
                //本地还有，直接在本地扣
                this.num--;
                log.info("用户{}在节点{}秒杀成功",username,name);

                this.successNum++;
                if(this.successNum==gap){
                    this.redis.incr(key,-this.successNum);
                    this.successNum = 0;
                    //模拟一个节点崩溃
                    if(name.equals("node9")){
                        error = true;
                    }
                }
            }
        }finally {
            segmentLock.unlock(errorKey);
        }
    }

    public String getName() {
        return name;
    }
}
